<template>
    <div
        class="anchor"
        :class="{
            'anchor-right': menuDirection == 'right',
            'anchor-left': menuDirection == 'left',
            'anchor-top': menuDirection == 'top',
            'anchor-bottom': menuDirection == 'bottom'
        }"
        ref="tabContainer"
    >
        <!-- 菜单部分 -->
        <div
            class="menu"
            :style="{ height: $props.menuDirection == 'top' ? 'auto' : contentHeight + 'px' }"
        >
            <el-scrollbar ref="menuScrollbarRef">
                <AnchorMenu
                    :data="data"
                    :modelValue="modelValue"
                    @choseMenu="choseMenu"
                    :menuDirection="$props.menuDirection == 'top' ? 'row' : 'column'"
                >
                </AnchorMenu>
            </el-scrollbar>
        </div>
        <!-- 滚动体 -->
        <div ref="contentRef" class="content" :style="{ height: contentHeight + 'px' }">
            <el-scrollbar ref="scrollbarRef" @scroll="contScroll">
                <div
                    ref="contentItemRef"
                    class="cy-content-item"
                    :id="'cyContentItem' + item.key"
                    v-for="(item, index) in contentList"
                >
                    <component :is="item.component" v-bind="item.attrs" :name="item.name">
                    </component>
                </div>
            </el-scrollbar>
        </div>
    </div>
</template>

<script setup>
import { useIntersectionObserver } from '@vueuse/core'
import { computed, onMounted, reactive, ref } from 'vue'

import AnchorMenu from '../anchorMenu/index.vue'
const props = defineProps({
    data: {
        type: Array,
        default: () => {
            return [
                {
                    name: '基本信息', // 标题名称
                    key: '2' // 唯一key
                },
                {
                    name: '排放口',
                    key: '3'
                }
            ]
        }
    },
    modelValue: { type: [Number, String] },
    menuDirection: {
        type: String,
        default: 'right'
    }, // 菜单方向
    height: {
        type: [Number, String],
        default: 500
    } // 内容高度(若不设置，将计算不超出主框架的最大高度)
})
const contentRef = ref(null)
const contentItemRef = ref([])
const VisibleView = ref({})
const menuScrollbarRef = ref(null)
const scrollbarRef = ref(null)
const contentState = reactive({
    // 内容盒子相关属性
    scrollTop: 0, // 滚动的距离
    offsetTop: 0, // 初始距离浏览器边框距离
    step: 10 // 每次滚动步长
})

let contentHeight = ref(300) // 主体内容高度

// 点击菜单
const choseMenu = (key) => {
    pageScrollTo(key)
}
// 纵向滚动到指定的位置
const pageScrollTo = (key) => {
    let dom = document.getElementById('cyContentItem' + key)
    const offset = dom ? dom.offsetTop : null
    offset.toString() ? scrollbarRef.value.setScrollTop(offset) : ''
}
const contScroll = ({ scrollTop }) => {
    contentState.scrollTop = scrollTop
    anchor()
}
const emit = defineEmits(['update:modelValue'])
// 元素滚动到视口，则选中该index
const anchor = () => {
    const contentItem = document.getElementsByClassName('cy-content-item')
    for (let i = 0; i < contentItem.length; i++) {
        let item = contentItem.item(i)

        let itemoffsetTop = item.offsetTop

        if (
            Math.abs(itemoffsetTop - contentState.scrollTop) <
            item.offsetHeight - contentHeight.value / 3
        ) {
            let value = item.id.replace('cyContentItem', '')
            emit('update:modelValue', value)
            menuOffset()
            return
        }
    }
}
const menuOffset = () => {
    if (props.modelValue) {
        let dom = document.getElementById('cyAuchorMenu' + props.modelValue)
        if (dom) {
            let offsetHet = dom.offsetTop
            if (offsetHet - contentHeight.value / 2 > 0)
                menuScrollbarRef.value.setScrollTop(offsetHet - contentHeight.value / 2)
            else if (offsetHet < contentHeight.value) menuScrollbarRef.value.setScrollTop(0)
        }
    }
}
const init = () => {
    // 初始化属性值
    contentState.offsetTop = contentRef.value.offsetTop
    if (props.height) {
        contentHeight.value = props.height
    }
}
onMounted(() => {
    init()
    menuOffset()
    contentList.value.forEach((i, index) => {
        VisibleView.value[index] = false
        useIntersectionObserver(
            contentItemRef.value[index],
            ([{ isIntersecting }]) => {
                if (isIntersecting) {
                    VisibleView.value[index] = isIntersecting
                }
            },
            contentRef
        )
    })
})

const contentList = computed(() => {
    let res = []
    let fn = (data) => {
        data.forEach((item) => {
            let copyItem = { ...item }
            res.push(copyItem)
            if (item.children) {
                fn(item.children)
            }
        })
    }
    props.data ? fn(props.data) : ''
    return res
})
</script>
<script>
export default {
    name: 'AnchorGroup'
}
</script>

<style lang="scss" scoped>
.anchor {
    background-color: #fff;
    display: flex;
    justify-content: flex-start;
    padding: 10px 0;
    &-left {
        flex-direction: row;
    }

    &-right {
        flex-direction: row-reverse;
    }

    &-top {
        flex-direction: column;
    }

    .content {
        width: 100%;
    }

    .content-item {
        padding-right: 20px;
        min-height: 200px;
        margin: 10px 0;
    }
}

.menu {
    position: relative;
    margin: 0 20px;
    display: inline-block;
    height: auto;
    position: relative;
}
</style>
